package io.github.yotta.logger.core;

import io.github.yotta.logger.anno.annotation.provider.NullBizProvider;
import io.github.yotta.logger.core.aop.LogAdvisor;
import io.github.yotta.logger.core.aop.LogPointcut;
import io.github.yotta.logger.core.aop.LoggerInterceptor;
import io.github.yotta.logger.core.support.BizIdProviderDiscover;
import io.github.yotta.logger.core.support.DefaultLogMetaDataDiscover;
import io.github.yotta.logger.core.support.LogContext;
import io.github.yotta.logger.core.support.LogMetaDataDiscover;
import io.github.yotta.logger.message.producer.LogDataProducer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author yotta
 * @date 2023/3/22 15:25
 */
@Configuration
@Slf4j
@EnableConfigurationProperties(LogProperties.class)
public class LogCoreAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean({BizIdProviderDiscover.class})
    public BizIdProviderDiscover bizIdProviderDiscover() {
        return new BizIdProviderDiscover();
    }


    @Bean
    @ConditionalOnMissingBean({LogMetaDataDiscover.class})
    public LogMetaDataDiscover logMetaDataDiscover(LogProperties logProperties) {
        return new DefaultLogMetaDataDiscover(logProperties);
    }

    @Bean
    @ConditionalOnMissingBean({LogPointcut.class})
    public LogPointcut logPointcut(LogMetaDataDiscover logMetaDataDiscover) {
        return new LogPointcut(logMetaDataDiscover);
    }

    @Bean
    @ConditionalOnMissingBean({LoggerInterceptor.class})
    public LoggerInterceptor loggerInterceptor(LogContext logContext,
                                               LogMetaDataDiscover logMetaDataDiscover,
                                               LogDataProducer logDataProducer,
                                               BizIdProviderDiscover bizIdProviderDiscover
    ) {
        return new LoggerInterceptor(logMetaDataDiscover, logContext, logDataProducer, bizIdProviderDiscover);
    }

    @Bean(name = "log.logAdvisor")
    public LogAdvisor logAdvisor(LogPointcut logPointcut, LoggerInterceptor loggerInterceptor) {
        final LogAdvisor logAdvisor = new LogAdvisor(logPointcut);
        logAdvisor.setAdviceBeanName("log.logAdvisor");
        // 设置通知
        logAdvisor.setAdvice(loggerInterceptor);
        return logAdvisor;
    }

    @Bean
    @ConditionalOnMissingBean({DefaultAdvisorAutoProxyCreator.class})
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
        final DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
        defaultAdvisorAutoProxyCreator.setProxyTargetClass(false);
        return defaultAdvisorAutoProxyCreator;
    }

    @Bean
    public NullBizProvider nullBizProvider() {
        return new NullBizProvider();
    }
}
